"""资产监听配置"""
from pydantic import BaseModel, Field
from bson import ObjectId
from typing import List


class PydanticObjectId(ObjectId):
    """python objectid 校验"""
    @classmethod
    def __get_validators__(cls):
        yield cls.validate

    @classmethod
    def validate(cls, v):
        if not ObjectId.is_valid(v):
            raise TypeError('ObjectId required')
        return ObjectId(v)


class _VulSettings(BaseModel):
    vul: List[str] = Field(..., name='漏洞列表')
    depth: int = Field(3, name='监听深度')
    maxPage: int = Field(1000, name='监听最大URL数')
    speed: str = Field(..., name='速度')


class _SSLSettings(BaseModel):
    pluginCategories: List[str] = Field(..., name='ssl监测类型')  # certificate protocol


class _SecurityEventSettings(BaseModel):
    plugins: List[str] = Field(..., name='安全事件列表')
    depth: int = Field(3, name='监听深度')
    maxPage: int = Field(1000, name='监听最大URL数')


class _AssetSettings(BaseModel):
    port: bool = Field(True, name='端口变动')
    subdomain: bool = Field(True, name='子域名变动')


class _ContentSettings(BaseModel):
    plugins: List[str] = Field(..., name='内容插件')
    keywordType: bool = Field(True, name='是否监听关键词')
    privacyDisclosureTypesType: bool = Field(True, name='是否监隐私内容')

    customKeywordTypes: List[int] = Field(..., name='用户敏感词类型')
    systemKeywordTypes: List[int] = Field(..., name='系统敏感词类型')

    privacyDisclosureTypes: List = Field(..., name='敏感词类型')
    depth: int = Field(3, name='监听深度')
    maxPage: int = Field(1000, name='监听最大URL数')
    includeUrl0: str = Field('/', name='开始页面')
    urlEnable: bool = Field(False, name='是否指定url')


class _customMonitorPage(BaseModel):
    excludeUrl: List = Field(..., name='排除url')
    includeUrl: List = Field(..., name='包含url')


class _Enable(BaseModel):
    asset: bool = Field(True, name='资产')
    content: bool = Field(True, name='内容')
    securityEvent: bool = Field(True, name='安全事件')
    ssl: bool = Field(True, name='ssl')
    vul: bool = Field(True, name='vul')


class _Notification(BaseModel):
    email: bool = Field(True, name='邮件')
    inBox: bool = Field(True, name='站内')
    sms: bool = Field(True, name='短信')
    wechat: bool = Field(True, name='微信')


class _AlertSettings(BaseModel):
    alertGroupIds: List[str] = Field(..., name='告警组列表')
    enable: _Enable = Field(..., name='监听类型')
    notification: _Notification = Field(..., name='通知')


class SingleConfig(BaseModel):
    """单次任务配置"""
    jobId: PydanticObjectId = Field(..., name='资产jobID')

    isSpecialTask: bool = Field(True, name='特殊任务')

    vulcollect: _VulSettings = Field(..., name='漏洞配置')
    sslcollect: _SSLSettings = Field(..., name='ssl配置')
    securityEventcollect: _SecurityEventSettings = Field(..., name='安全事件配置')
    assetcollect: _AssetSettings = Field(..., name='资产配置')
    contentcollect: _ContentSettings = Field(..., name='内容配置')

    cookie: str = Field(None, name='预登陆')
    customMonitorPage: _customMonitorPage = Field(None, name='自定义监测页面')

    alertSettings: _AlertSettings = Field(..., name='告警设置')


class _AllowTime(BaseModel):
    start: str = Field(..., name='开始时间')
    end: str = Field(..., name='开始时间')


class _PeriodAlertSettings(_AlertSettings):
    emailAllowedTime: _AllowTime = Field(..., name='')
    smsAllowedTime: _AllowTime = Field(..., name='')
    emailDailyLimit: int = Field(10, name='')
    smsDailyLimit: int = Field(10, name='')


class _PeriodsslSettings(BaseModel):
    enable: bool = Field(..., name='')
    interval: int = Field(..., name='')
    collect: _SSLSettings = Field(..., name='')


class _PeriodvulSettings(BaseModel):
    enable: bool = Field(..., name='')
    enableSitePortraitTriggerMonitor: bool = Field(..., name='')
    interval: int = Field(..., name='')
    collect: _VulSettings = Field(..., name='')
    vulType: List[str] = Field(..., name='')


class _PeriodsecurityEventSettings(BaseModel):
    enable: bool = Field(..., name='')
    interval: int = Field(..., name='')
    collect: _SecurityEventSettings = Field(..., name='')


class _PeriodassetSettings(BaseModel):
    enable: bool = Field(..., name='')
    interval: int = Field(..., name='')
    collect: _SecurityEventSettings = Field(..., name='')


class _PeriodcontentSettings(BaseModel):
    enable: bool = Field(..., name='')
    interval: int = Field(..., name='')
    collect: _ContentSettings = Field(..., name='')


class _pingAlert(BaseModel):
    alertCount: int = Field(1, name='告警次数')
    enable: bool = Field(True, name='')
    lossRate: int = Field(50)
    nodeCount: int = Field(5)
    respTime: int = Field(1000)


class _httpAlert(_pingAlert):
    """"""
    respTime: int = Field(12000)
    include: list = Field([], name='')


class _httpCollect(BaseModel):
    area: list = ["chengdu-cmc", "huhehaote-cuc", "tx-wuhan", "beijing-cuc", "tx-xian"]
    header: str = ""
    method: str = "get"
    redirect: int = 3


class _HttpSettings(BaseModel):
    alert: _httpAlert = Field(..., name='')
    statusCodeRange: List[list] = Field([['400', '599']])
    collect: _httpCollect = Field(...)
    enable: bool = True
    enableSitePortraitTriggerMonitor: bool = False
    interval: int = 300000
    name: str = ""
    target: str = ""


class _PingSettings(_HttpSettings):
    pass


class PeriodConfig(BaseModel):
    """周期任务配置"""
    jobId: PydanticObjectId = Field(..., name='资产jobID')

    enableAlert: bool = Field(None, name='开启告警')
    enableMonitor: bool = Field(None, name='开启监测')

    cookie: str = Field(None, name='预登陆')
    customMonitorPage: _customMonitorPage = Field(None, name='自定义监测页面')

    vulSettings: _PeriodvulSettings = Field(..., name='漏洞配置')
    sslSettings: _PeriodsslSettings = Field(..., name='ssl设置')

    securityEventSettings: _PeriodsecurityEventSettings = Field(..., name='安全事件配置')
    assetcollect: _PeriodassetSettings = Field(..., name='资产配置')

    contentSettings: _PeriodcontentSettings = Field(..., name='内容设置')

    httpSettings: List[_HttpSettings] = Field(..., name='http设置')
    pingSettings: List[_PingSettings] = Field(..., name='ping设置')

    alertSettings: _PeriodAlertSettings = Field(..., name='告警设置')
